import { _decorator, AudioClip, Component, Node, randomRangeInt, tween, UIOpacity, UITransform, v3, Vec3 } from 'cc';
import JiuJiuXiaoDongWu_GameManager from './JiuJiuXiaoDongWu_GameManager';
import { bdlMgr } from 'db://assets/Script/Manager/BundleManager_S';
import { SSS_Consts } from 'db://assets/Script/Data/SSS_Consts';
import { SSS_AudioManager } from 'db://assets/Script/Manager/SSS_AudioManager';
const { ccclass, property } = _decorator;

interface BlockResult {
    node: Node;
    dist: number;
}

@ccclass('JiuJiuXiaoDongWu_Yang')
export class JiuJiuXiaoDongWu_Yang extends Component {
    @property([Node])
    sprite_list: Node[] = [];

    is_out = false; // 是否已经出界
    type = 0; // 0 表示 猫 1 表示 狗
    long_distance = 1000;

    onLoad() {
        for (let index = 0; index < this.sprite_list.length; index++) {
            const node = this.sprite_list[index];
            node.active = false;
        }

        this.type = randomRangeInt(0, this.sprite_list.length);
        this.sprite_list[this.type].active = true;

        this.node.on(Node.EventType.TOUCH_END, () => {
            this.onClickNodeA(this.node);
        }, this);
    }

    /** 获取节点的世界角度 */
    getWorldAngle(node: Node): number {
        let angle = node.angle;
        let parent = node.parent;
        while (parent) {
            angle += parent.angle;
            parent = parent.parent;
        }
        return angle;
    }

    /** 获取节点的正方向 (默认 0° = Y+ 上方) */
    getForwardDir(node: Node): Vec3 {
        // const rad = node.angle * Math.PI / 180;
        // return new Vec3(-Math.sin(rad), Math.cos(rad), 0).normalize();

        const rad = this.getWorldAngle(node) * Math.PI / 180;
        return new Vec3(-Math.sin(rad), Math.cos(rad), 0).normalize();
    }

    /** 获取矩形的四个顶点（世界坐标，支持旋转） */
    getWorldRectPoints(node: Node): Vec3[] {
        const trans = node.getComponent(UITransform)!;
        const w = trans.width / 2;
        const h = trans.height / 2;

        const localPoints = [
            new Vec3(-w, -h, 0),
            new Vec3(w, -h, 0),
            new Vec3(w, h, 0),
            new Vec3(-w, h, 0),
        ];

        const worldPoints: Vec3[] = [];
        const mat = node.getWorldMatrix();
        for (let p of localPoints) {
            const wp = new Vec3();
            Vec3.transformMat4(wp, p, mat);
            worldPoints.push(wp);
        }
        return worldPoints;
    }

    /** 检查 A 前方是否被 B 阻挡，返回交点距离（无阻挡则返回 null） */
    rayIntersectsRect(nodeA: Node, dir: Vec3, nodeB: Node): number | null {
        const transA = nodeA.getComponent(UITransform)!;
        const halfLen = transA.height / 2;
        const edgeA = nodeA.worldPosition.clone().add(dir.clone().multiplyScalar(halfLen));
        const pointsB = this.getWorldRectPoints(nodeB);

        let minDist: number | null = null;
        const EPSILON = 1e-4; // 浮点误差阈值

        for (let i = 0; i < 4; i++) {
            const p1 = pointsB[i];
            const p2 = pointsB[(i + 1) % 4];

            const inter = this.raySegmentIntersection(edgeA, dir, p1, p2);
            if (inter) {
                const v = inter.clone().subtract(edgeA);
                const dist = v.length();
                if (v.dot(dir) > 0) { // 确认在前方
                    // 误差处理：距离极小视为0
                    const finalDist = dist < EPSILON ? 0 : dist;
                    if (minDist === null || finalDist < minDist) {
                        minDist = finalDist;
                    }
                }
            }
        }
        return minDist;
    }

    /** 射线和线段求交点 */
    raySegmentIntersection(ro: Vec3, rd: Vec3, p1: Vec3, p2: Vec3): Vec3 | null {
        const v1 = new Vec3(ro.x - p1.x, ro.y - p1.y, 0);
        const v2 = new Vec3(p2.x - p1.x, p2.y - p1.y, 0);
        const v3 = new Vec3(-rd.y, rd.x, 0); // 射线垂直向量

        const dot = v2.dot(v3);
        if (Math.abs(dot) < 1e-6) return null; // 平行

        const t1 = (v2.x * v1.y - v2.y * v1.x) / dot;
        const t2 = v1.dot(v3) / dot;

        if (t1 >= 0 && t2 >= 0 && t2 <= 1) {
            return new Vec3(ro.x + t1 * rd.x, ro.y + t1 * rd.y, 0);
        }
        return null;
    }

    /** 获取 A 前方的所有阻挡物，按距离排序 */
    getForwardBlockList(nodeA: Node): BlockResult[] {
        const dir = this.getForwardDir(nodeA);
        const results: BlockResult[] = [];

        for (let nodeB of JiuJiuXiaoDongWu_GameManager.Instance.arr_node) {
            if (nodeB === nodeA) continue;
            if (nodeB.getComponent(JiuJiuXiaoDongWu_Yang).is_out) continue;

            const dist = this.rayIntersectsRect(nodeA, dir, nodeB);
            if (dist !== null) {
                results.push({ node: nodeB, dist });
            }
        }

        // 按距离升序排列
        results.sort((a, b) => a.dist - b.dist);
        return results;
    }

    /**
     * 让物体反向（旋转180°）
     * @param node 需要反向的节点
     */
    reverseDirection(node: Node) {
        node.angle += 180;
        // 保证角度在0~360范围内
        node.angle = ((node.angle % 360) + 360) % 360;
    }

    /** 点击物体 A，扫描前方所有阻挡物 */
    onClickNodeA(nodeA: Node) {
        this.PlaySound();

        // console.log('JiuJiuXiaoDongWu_GameManager.Instance.fz_flag:', JiuJiuXiaoDongWu_GameManager.Instance.fz_flag);
        if (JiuJiuXiaoDongWu_GameManager.Instance.fz_flag == true) {
            this.reverseDirection(nodeA);

            JiuJiuXiaoDongWu_GameManager.Instance.fz_flag = false;
            JiuJiuXiaoDongWu_GameManager.Instance.chooose.active = false;
            JiuJiuXiaoDongWu_GameManager.Instance.btns.active = true;
        }
        else {
            const list = this.getForwardBlockList(nodeA);
            list.sort((a, b) => a.dist - b.dist);
            // console.log('list--------', list);

            let node1;

            if (list.length > 0) {
                node1 = list[0].node;
                let dist1 = this.recalcDistanceToBlock(nodeA, node1);

                // console.log(`物体 ${nodeA.name} 前方的阻挡物列表:`);
                list.forEach(r => {
                    // console.log(`  ${r.node.name}, 距离 ${r.dist.toFixed(2)}`);

                    const blockNode = r.node // 你的阻挡物体节点
                    const dist = this.recalcDistanceToBlock(nodeA, blockNode);
                    // console.log('重新计算的距离:', dist);

                    if (dist < dist1) {
                        node1 = blockNode;
                    }

                    tween(r.node.getComponent(UIOpacity))
                        .to(0.14, { opacity: 140 })
                        .to(0.14, { opacity: 255 })
                        .to(0.14, { opacity: 140 })
                        .to(0.14, { opacity: 255 })
                        .start();

                });
            } else {
                console.log(`物体 ${nodeA.name} 前方没有障碍`);
            }

            // console.log('node1--------', node1);

            this.moveToBlockFront(nodeA, node1)
        }
    }

    /**
     * 重新计算当前节点到指定阻挡物体的最近距离（从中心点出发）
     * @param nodeA 当前节点
     * @param nodeB 阻挡物体节点
     * @returns 最近距离（无交点返回 null）
     */
    recalcDistanceToBlock(nodeA: Node, nodeB: Node): number | null {
        const dir = this.getForwardDir(nodeA);
        const centerA = nodeA.worldPosition.clone();
        const pointsB = this.getWorldRectPoints(nodeB);

        let minDist: number | null = null;
        const EPSILON = 1e-4;

        for (let i = 0; i < 4; i++) {
            const p1 = pointsB[i];
            const p2 = pointsB[(i + 1) % 4];

            const inter = this.raySegmentIntersection(centerA, dir, p1, p2);
            if (inter) {
                const v = inter.clone().subtract(centerA);
                const dist = v.length();
                if (v.dot(dir) > 0) {
                    const finalDist = dist < EPSILON ? 0 : dist;
                    if (minDist === null || finalDist < minDist) {
                        minDist = finalDist;
                    }
                }
            }
        }
        return minDist;
    }

    /**
     * 根据recalcDistanceToBlock获取的距离，移动物体到阻挡物体前方
     */
    moveToBlockFront(nodeA: Node, blockNode: Node) {
        const dir = this.getForwardDir(nodeA);
        let dist
        if (blockNode) {
            dist = this.recalcDistanceToBlock(nodeA, blockNode);
        }
        else {
            dist = this.long_distance;

            this.is_out = true; // 标记为已出界
        }


        // console.log('重新计算的距离:--------', dist);

        const transA = nodeA.getComponent(UITransform)!;
        const EPSILON = 1e-4;
        const SAFE_MARGIN = 0; // 安全缓冲距离，单位像素

        if (dist === null || dist < EPSILON) {
            console.log('无法移动，距离过小或没有交点');
            return;
        }

        // 计算自身边缘到中心的距离（支持任意方向和旋转）
        const pointsA = this.getWorldRectPoints(nodeA);
        let maxDot = -Infinity;
        let edgeOffset = 0;
        for (let i = 0; i < pointsA.length; i++) {
            const offset = pointsA[i].subtract(nodeA.worldPosition).dot(dir);
            if (offset > maxDot) {
                maxDot = offset;
                edgeOffset = offset;
            }
        }

        // 移动距离 = 距离 - 自身边缘到中心的距离 - 安全缓冲
        const moveDist = dist - edgeOffset - SAFE_MARGIN;
        if (moveDist < EPSILON) {
            console.log('自身已贴边，无法移动');
            return;
        }

        // 从中心点出发，移动距离为moveDist
        const targetPos = nodeA.worldPosition.clone().add(dir.clone().multiplyScalar(moveDist));
        const parent = nodeA.parent!;
        const localTargetPos = parent.getComponent(UITransform)?.convertToNodeSpaceAR(targetPos) || targetPos;

        const currentPos = nodeA.position.clone();
        const actualDistance = currentPos.subtract(localTargetPos).length();
        // console.log('actualDistance----------------:', actualDistance);

        // 设置固定的移动速度（单位：单位/秒）
        const moveSpeed = 1200; // 根据你的需求调整这个值

        // 根据距离和速度计算所需时间
        const duration = actualDistance / moveSpeed;
        // console.log('duration:', duration);

        tween(nodeA)
            .to(duration, { position: localTargetPos })
            .call(() => {
                if (this.is_out) {
                    this.Destroy();
                }

                if (JiuJiuXiaoDongWu_GameManager.Instance.arr_node.length == 0) {
                    JiuJiuXiaoDongWu_GameManager.Instance.gameOver();
                }
            })
            .start();
    }

    Destroy() {
        this.node.active = false;

        let index = JiuJiuXiaoDongWu_GameManager.Instance.arr_node.indexOf(this.node);
        if (index !== -1) {
            JiuJiuXiaoDongWu_GameManager.Instance.arr_node.splice(index, 1);
        }

        // console.log('JiuJiuXiaoDongWu_GameManager.Instance.arr_node.length-------:', JiuJiuXiaoDongWu_GameManager.Instance.arr_node.length);
    }

    PlaySound() {
        let arr = ["猫", "狗"];
        let name = arr[this.type];
        bdlMgr.getRes<AudioClip>(SSS_Consts.BundleName.AUDIO, `audio/${name}`, AudioClip).then(res => {
            SSS_AudioManager.Instance.playSFX(res, false);
        });
    }
}